package woaini.wind.bot.job.qylc;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.math.MathUtil;
import cn.hutool.core.text.csv.CsvData;
import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvRow;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import woaini.wind.bot.core.event.segment.Messages;
import woaini.wind.bot.core.internal.Internal;
import woaini.wind.bot.core.manager.BotManager;
import woaini.wind.bot.job.vo.OpenLogSummaryVO;
import woaini.wind.bot.job.vo.OpenPushSummaryVO;
import woaini.wind.bot.job.vo.OpenSummaryVO;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * QYLC线上预警任务
 * 每10分钟执行一次 如果超过预警阈值 则发送预警信息
 * 每天早上9点执行一次 查询昨天的预警信息 提示存在如果存在异常请及时处理
 * 每天下午5点执行一次 提示今日总和
 * @see woaini.wind.bot.job.qylc.QYLCEarlyWarningJob
 * @author yefeng {@date 2025-01-15 21:56:40}
 */
@Service(value = "QYLCEarlyWarningJob")
@Slf4j
public class QYLCEarlyWarningJob {

  private static Map<String, String> URL_CONFIG_MAP;

  @Value("${qylc.warning-group}")
  private String warningGroup;

  /**
   * @see TimedCache<String, String> 定时缓存 默认一分钟
   */
  public static TimedCache<String, String> timedCache = CacheUtil.newTimedCache(60 * 1000);

  static {
    timedCache.schedulePrune(5 * 60 * 1000);
  }

  /** 预警相关的阈值 */
  public static final int threshold = 10;

  static {
    URL_CONFIG_MAP = new HashMap<>();
    URL_CONFIG_MAP.put("xj", "https://openmall.knsyxw.com/api/openDis/summary");
    URL_CONFIG_MAP.put("hgs", "https://openmall.hgscn.com/api/openDis/summary");
    URL_CONFIG_MAP.put("gylw", "");
  }

  public void earlyWarning() {

    StringBuilder sb = new StringBuilder();
    sb.append("【预警信息】\n");
    //是否触发预警
    AtomicBoolean warning = new AtomicBoolean(false);

    String toDay = LocalDate.now().toString();

    String requestJson = STR."""
       {
           "startTime": "\{toDay} 00:00:00",
           "endTime": "\{toDay} 23:59:59"
       }
    """.trim();

    // 请求获取预警信息
    URL_CONFIG_MAP.forEach((env, url)->{
      if (StrUtil.isEmpty(url)){
        return;
      }
      //判断预警是不是被屏蔽了
      if (timedCache.containsKey(env)){
        return;
      }
      StringBuilder tmp = new StringBuilder();

      tmp.append(STR."平台:\{env}\n");

      //获取数据
      String body = HttpRequest.post(url).body(requestJson).execute().body();
      OpenSummaryVO openSummaryVO = JSONObject.parseObject(body, OpenSummaryVO.class);
      OpenLogSummaryVO logSummary = openSummaryVO.getLogSummary();
      long logErrorCount = logSummary.getErrorCount();
      long logAllCount = logSummary.getAllCount();
      if (logErrorCount > threshold){
          warning.set(true);
        tmp.append(STR."[http请求]异常预警\{logErrorCount},总:\{logAllCount},错误率:\{errorRate(logErrorCount,logAllCount)}%\n");
      }
      OpenPushSummaryVO pushSummary = openSummaryVO.getPushSummary();
      long pushErrorCount = pushSummary.getErrorCount();
      long pushAllCount = pushSummary.getAllCount();
      if (pushErrorCount > threshold){
        warning.set(true);
        tmp.append(STR."[第三方推送]异常预警\{pushErrorCount},总:\{pushAllCount},错误率:\{errorRate(pushErrorCount,pushAllCount)}%\n");
      }
      if (warning.get()){
        sb.append(tmp);
      }
    });
    //推送预警信息 如果需要预警
    if (warning.get()){
      Internal internal = BotManager.getBot("李风儿", "wx").internal();
      log.info(sb.toString());
      internal.sendGroupMessage(warningGroup, Messages.builder().text(sb.toString()));
    }
  }

  public void startWorkingEarlyWarningReport() {
    //开始工作报告预警 每天早上九点执行 获取数据时间范围为昨天到今天的数据
    String toDay = LocalDate.now().toString();
    String yesterday = LocalDate.now().plusDays(-1).toString();

    //获取值班人员
    CsvReader reader = CsvUtil.getReader();  // 进行创建csv读取器

    // 设置文件读取的分隔符
    reader.setFieldSeparator(' '); // 默认为 , 可不进行设置
    CsvData data = reader.read(FileUtil.file("/home/xiuyuan/tmp/ai/work/workInfo.csv"), StandardCharsets.UTF_8);
    CsvRow csvRow = data.getRows().stream().filter(d -> d.get(0).equals(toDay)).findFirst().orElse(null);
    String workingUser = "未设置";
    if (csvRow != null){
      workingUser = csvRow.get(2);
    }

    String requestJson = STR."""
       {
           "startTime": "\{yesterday} 00:00:00",
           "endTime": "\{toDay} 23:59:59"
       }
    """.trim();
    StringBuilder sb = new StringBuilder();
    sb.append("【异常日报】\n");
    sb.append(STR."早上好,今天值班人员是[\{workingUser}],请好好值班哦!!!\n");
    sb.append(STR."以下是昨天到现在的简报,请查收\n");

    AtomicBoolean warning = new AtomicBoolean(false);

    URL_CONFIG_MAP.forEach((env, url)->{
      if (StrUtil.isEmpty(url)){
        return;
      }
      StringBuilder tmp = new StringBuilder();

      tmp.append(STR."平台:\{env}\n");

      //获取数据
      String body = HttpRequest.post(url).body(requestJson).execute().body();
      OpenSummaryVO openSummaryVO = JSONObject.parseObject(body, OpenSummaryVO.class);
      OpenLogSummaryVO logSummary = openSummaryVO.getLogSummary();
      long logErrorCount = logSummary.getErrorCount();
      long logAllCount = logSummary.getAllCount();
      if (logErrorCount > 0){
        warning.set(true);
        tmp.append(STR."[http请求]异常报告\{logErrorCount},总:\{logAllCount},错误率:\{errorRate(logErrorCount,logAllCount)}%\n");
      }
      OpenPushSummaryVO pushSummary = openSummaryVO.getPushSummary();
      long pushErrorCount = pushSummary.getErrorCount();
      long pushAllCount = pushSummary.getAllCount();
      if (pushErrorCount > 0){
        warning.set(true);
        tmp.append(STR."[第三方推送]异常报告\{pushErrorCount},总:\{pushAllCount},错误率:\{errorRate(pushErrorCount,pushAllCount)}%\n");
      }
      if (warning.get()){
        sb.append(tmp);
      }
    });

    if (warning.get()){
      Internal internal = BotManager.getBot("李风儿", "wx").internal();
      log.info(sb.toString());
      internal.sendGroupMessage(warningGroup, Messages.builder().text(sb.toString()));
    }else {
      Internal internal = BotManager.getBot("李风儿", "wx").internal();
      log.info(sb.toString());
      internal.sendGroupMessage(warningGroup, Messages.builder().text(STR."早上好,今天值班人员是\{workingUser}],请关注群里信息哦!!!"));
    }
  }

  public BigDecimal errorRate(long errorCount, long allCount){
    BigDecimal divide = new BigDecimal(errorCount).divide(new BigDecimal(allCount),4, RoundingMode.HALF_UP);
    return divide.multiply(new BigDecimal(100));
  }
}
